package com.xuelang.pipeline.artifact.infrastructure.resource.repository;

import cn.hutool.core.util.ObjectUtil;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.xuelang.pipeline.artifact.client.common.result.PageRecord;
import com.xuelang.pipeline.artifact.client.resource.dto.ToolChainQuery;
import com.xuelang.pipeline.artifact.client.resource.enums.ToolChainTypeEnum;
import com.xuelang.pipeline.artifact.domain.resource.ToolChain;
import com.xuelang.pipeline.artifact.domain.resource.repository.ToolChainRepository;
import com.xuelang.pipeline.artifact.infrastructure.resource.converter.ToolChainToToolChainDOConverter;
import com.xuelang.pipeline.artifact.infrastructure.resource.dataobject.ToolChainDO;
import com.xuelang.pipeline.artifact.infrastructure.resource.mapper.ToolChainMapper;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Repository;

import java.util.List;
import java.util.stream.Collectors;

/**
 * 工具链仓库实现类
 *
 * @author xiwen.zxg
 * @since 2024/5/15
 */
@Slf4j
@Repository
public class ToolChainRepositoryImpl implements ToolChainRepository {

    @Autowired
    ToolChainMapper toolChainMapper;

    @Override
    public PageRecord<ToolChain> pageList(long currentPage, long pageSize, ToolChainQuery toolChainQuery) {
        currentPage = currentPage < 1 ? 1 : currentPage;
        pageSize = pageSize < 1 ? 10 : pageSize;
        Page<ToolChainDO> page = new Page<>(currentPage, pageSize);
        LambdaQueryWrapper<ToolChainDO> wrapper = Wrappers.lambdaQuery(ToolChainDO.class);
        wrapper.eq(ToolChainDO::getType, (toolChainQuery == null || toolChainQuery.getType() == null) ? ToolChainTypeEnum.TYPE_UNKNOWN.getTypeKey() : toolChainQuery.getType());
        if (toolChainQuery != null) {
            if (StringUtils.isNotBlank(toolChainQuery.getCode())) {
                wrapper.like(ToolChainDO::getCode, toolChainQuery.getCode());
            }
            if (StringUtils.isNotBlank(toolChainQuery.getCondition())) {
                wrapper.like(ToolChainDO::getVersion, toolChainQuery.getCondition());
            }
        }
        toolChainMapper.selectPage(page, wrapper);
        return new PageRecord<>(
                page.getCurrent(),
                page.getSize(),
                page.getTotal(),
                page.getPages(),
                page.getRecords().stream().map(ToolChainToToolChainDOConverter.INSTANCE::toolChainDOToToolChain).collect(Collectors.toList())
        );
    }

    @Override
    public List<ToolChain> list(ToolChainQuery toolChainQuery) {
        LambdaQueryWrapper<ToolChainDO> wrapper = Wrappers.lambdaQuery(ToolChainDO.class);
        wrapper.eq(ToolChainDO::getType, (toolChainQuery == null || toolChainQuery.getType() == null) ? ToolChainTypeEnum.TYPE_UNKNOWN.getTypeKey() : toolChainQuery.getType());
        if (toolChainQuery != null) {
            if (StringUtils.isNotBlank(toolChainQuery.getCode())) {
                wrapper.like(ToolChainDO::getCode, toolChainQuery.getCode());
            }
            if (StringUtils.isNotBlank(toolChainQuery.getCondition())) {
                wrapper.like(ToolChainDO::getVersion, toolChainQuery.getCondition());
            }
        }
        return toolChainMapper.selectList(wrapper).stream()
                .map(ToolChainToToolChainDOConverter.INSTANCE::toolChainDOToToolChain).collect(Collectors.toList());
    }


    @Override
    public Boolean save(ToolChain toolChain) {
        return toolChainMapper.insert(ToolChainToToolChainDOConverter.INSTANCE.toolChainToToolChainDO(toolChain)) == 1;
    }

    @Override
    public Boolean update(ToolChain toolChain) {
        return toolChainMapper.update(
                ToolChainToToolChainDOConverter.INSTANCE.toolChainToToolChainDO(toolChain),
                Wrappers.lambdaQuery(ToolChainDO.class).eq(ToolChainDO::getCode, toolChain.getCode())) == 1;
    }

    @Override
    public Boolean delete(String code) {
        return toolChainMapper.delete(Wrappers.lambdaQuery(ToolChainDO.class).eq(ToolChainDO::getCode, code)) == 1;
    }

    @Override
    public ToolChain query(String code) {
        ToolChainDO toolChainDO = toolChainMapper.selectOne(Wrappers.lambdaQuery(ToolChainDO.class).eq(ToolChainDO::getCode, code));
        return ToolChainToToolChainDOConverter.INSTANCE.toolChainDOToToolChain(toolChainDO);
    }

    @Override
    public Boolean existsVersion(String code, Integer type, String version) {
        List<ToolChainDO> toolChainDOS = toolChainMapper.selectList(Wrappers.lambdaQuery(ToolChainDO.class)
                .eq(ToolChainDO::getVersion, version)
                .eq(ToolChainDO::getType, type)
        );
        if (ObjectUtil.isEmpty(toolChainDOS)) {
            return false;
        }
        return toolChainDOS.stream().anyMatch(toolChainDO -> !ObjectUtil.equals(code, toolChainDO.getCode()));
    }

}
